package com.weifly.weistock.web.controller.module;

import com.weifly.weistock.bo.MergeRecordResult;
import com.weifly.weistock.core.common.Result;
import com.weifly.weistock.core.common.StockException;
import com.weifly.weistock.core.constant.StockCatalogEnum;
import com.weifly.weistock.core.market.StockKLineService;
import com.weifly.weistock.core.market.bo.StockDayBO;
import com.weifly.weistock.core.market.bo.StockKLineBO;
import com.weifly.weistock.core.util.ConvertUtils;
import com.weifly.weistock.core.util.WeistockUtils;
import com.weifly.weistock.module.stockdata.StockDataConverter;
import com.weifly.weistock.module.stockdata.StockDataHoldService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.weifly.weistock.core.constant.WeistockConstants.PAGE_LIMIT;

/**
 * 股票历史数据管理
 *
 * @author weifly
 * @since 2021/6/11
 */
@Controller
@RequestMapping(value = "/module/stockData")
public class StockDataController {

    private Logger log = LoggerFactory.getLogger(StockDataController.class);

    @Autowired
    private StockDataHoldService stockDataHoldService;

    @Autowired
    private StockKLineService stockKLineService;

    /**
     * 首页
     */
    @RequestMapping(value = "/index")
    public String index() {
        return "module/stockData/index";
    }

    /**
     * 股票历史数据列表
     */
    @RequestMapping(value = "/stockList")
    public String stockList() {
        return "module/stockData/stockList";
    }

    /**
     * 获取股票记录列表
     */
    @RequestMapping(value = "/getStockList")
    @ResponseBody
    public Result getStockList() {
        List<StockKLineBO> stockDataList = this.stockDataHoldService.getStockDataList();
        List<Map<String, Object>> infoList = ConvertUtils.convert(stockDataList, StockDataConverter::convertToStockDataDTO);
        return Result.createSuccessResult(infoList);
    }

    /**
     * 天数据列表
     */
    @RequestMapping(value = "/dayList")
    public String dayList() {
        return "module/stockData/dayList";
    }

    /**
     * 加载天数据列表
     */
    @RequestMapping("/getDayList")
    @ResponseBody
    public Result getDayList(HttpServletRequest request) {
        try {
            List<StockDayBO> dayList = this.stockDataHoldService.getDayList(StockDataConverter.convertToGetDayListRequest(request, PAGE_LIMIT));
            boolean haveMore = false;
            if (dayList.size() > PAGE_LIMIT) {
                haveMore = true;
                dayList = dayList.subList(0, PAGE_LIMIT); // 只返回limit条记录
            }
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("haveMore", haveMore);
            dataMap.put("recordList", ConvertUtils.convert(dayList, StockDataConverter::convertToStockDayDTO));
            return Result.createSuccessResult(dataMap);
        } catch (StockException e) {
            return Result.createErrorResult(e);
        }
    }

    /**
     * 更新股票数据
     */
    @RequestMapping(value = "/updateStockData")
    public String updateStockData() {
        return "module/stockData/updateStockData";
    }

    /**
     * 执行更新
     */
    @RequestMapping("/doUpdateStockData")
    @ResponseBody
    public Result doUpdateStockData(HttpServletRequest request) {
        try {
            String stockCode = request.getParameter("stockCode");
            if (StringUtils.isBlank(stockCode)) {
                return Result.createErrorResult("缺少stockCode参数");
            }
            StockCatalogEnum stockCatalog = StockCatalogEnum.getByFullCode(stockCode);
            if (stockCatalog == null) {
                return Result.createErrorResult("不支持的stockCode");
            }
            StockKLineBO stockKLineBO = this.stockKLineService.loadStockKLine(stockCode);
            MergeRecordResult mergeRecordResult = this.stockDataHoldService.updateStockData(stockKLineBO);
            return Result.createSuccessResult(mergeRecordResult);
        } catch (StockException e) {
            return Result.createErrorResult(e);
        }
    }

    /**
     * 更新所有股票数据
     */
    @RequestMapping("/doUpdateAllStockData")
    @ResponseBody
    public Result doUpdateAllStockData(HttpServletRequest request) {
        try {
            List<StockKLineBO> stockDataList = this.stockDataHoldService.getStockDataList();
            for (StockKLineBO stockData : stockDataList) {
                StockKLineBO newStockKLineBO = this.stockKLineService.loadStockKLine(stockData.getStockCode());
                if (newStockKLineBO == null || newStockKLineBO.getDayList().isEmpty()) {
                    log.warn("无法加载KLine数据, stockCode={}, stockName={}", stockData.getStockCode(), stockData.getStockName());
                    continue;
                }
                MergeRecordResult mergeRecordResult = this.stockDataHoldService.updateStockData(newStockKLineBO);
                log.info("更新KLine数据，stockCode=" + newStockKLineBO.getStockCode() + ", result=" + WeistockUtils.toJsonString(mergeRecordResult));
            }
            return Result.createSuccessResult(null);
        } catch (StockException e) {
            return Result.createErrorResult(e);
        }
    }
}
